home *** CD-ROM | disk | FTP | other *** search
/ Ultimedia 2 / Ultimedia 2.iso / tools / animplayer / amipeg / source.lha / parseblock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-03  |  4.6 KB  |  209 lines

  1. /*
  2.  *  This source handles parsing and supervises decoding of the blocks and
  3.  *  passes the decoded data to the idct.
  4.  */
  5.  
  6.  
  7. #define NO_SANITY_CHECKS
  8. #include "video.h"
  9. #include "proto.h"
  10. #include "decoders.h"
  11.  
  12. #define static
  13.  
  14. /* External declarations. */
  15.  
  16. extern int zigzag_direct[];
  17.  
  18.  
  19. /*
  20.  *--------------------------------------------------------------
  21.  *
  22.  * ParseReconBlock --
  23.  *
  24.  *    Parse values for block structure from bitstream.
  25.  *      n is an indication of the position of the block within
  26.  *      the macroblock (i.e. 0-5) and indicates the type of 
  27.  *      block (i.e. luminance or chrominance). Reconstructs
  28.  *      coefficients from values parsed and puts in 
  29.  *      block.dct_recon array in vid stream structure.
  30.  *      sparseFlag is set when the block contains only one
  31.  *      coeffictient and is used by the IDCT.
  32.  *
  33.  * Results:
  34.  *    
  35.  *
  36.  * Side effects:
  37.  *      Bit stream irreversibly parsed.
  38.  *
  39.  *--------------------------------------------------------------
  40.  */
  41.  
  42. #define DCT_recon blockPtr->dct_recon
  43. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  44. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  45. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  46.  
  47. void ParseReconBlock(int n)
  48. {
  49.     Block *blockPtr = &curVidStream->block;
  50.     int diff, level, run, pos, coeff, qscale;
  51.     short int *reconptr=DCT_recon[0];
  52.     unsigned short *iqmatrixptr;
  53.  
  54.     if (bufLength < 100) correct_underflow();
  55.  
  56.     clear64words(reconptr=DCT_recon[0]);
  57.  
  58.     if (curVidStream->mblock.mb_intra) {
  59.  
  60.       if (n < 4) {    /* Get the luminance bits. */
  61.  
  62.       /* Parse and decode size of first coefficient and itself. */
  63.       DecodeDCTDCSizeLum(diff);
  64.  
  65.     if (n == 0) {
  66.       coeff = diff << 3;
  67.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  68.         coeff += 1024;
  69.       else coeff += DCT_dc_y_past;
  70.     } else
  71.       coeff = DCT_dc_y_past + (diff << 3);
  72.     DCT_dc_y_past = coeff;
  73.  
  74.       } else {
  75.     
  76.       /* Parse and decode size of first coefficient and itself. */
  77.       DecodeDCTDCSizeChrom(diff);
  78.  
  79.     if (n == 4) {
  80.       coeff = diff << 3;
  81.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  82.         coeff += 1024;
  83.       else
  84.         coeff += DCT_dc_cr_past;
  85.       DCT_dc_cr_past = coeff;
  86.  
  87.     } else {
  88.       coeff = diff << 3;
  89.       if (curVidStream->mblock.mb_address - curVidStream->mblock.past_intra_addr > 1) 
  90.         coeff += 1024;
  91.       else
  92.         coeff += DCT_dc_cb_past;
  93.       DCT_dc_cb_past = coeff;
  94.     }
  95.       }
  96.  
  97.       *reconptr = coeff;
  98.     
  99.       if (curVidStream->picture.code_type != 4) {
  100.     recon_intra(curVidStream->intra_quant_matrix_ptr[curVidStream->slice.quant_scale], reconptr);
  101.     flush_bits(2); // move to sutils.s?
  102.       }
  103.  
  104.     } else { /* not an intra-frame */
  105.       
  106.       qscale = curVidStream->slice.quant_scale;
  107.  
  108.       DecodeDCTCoeffFirst(run, level);
  109.       pos = zigzag_direct[run];
  110.  
  111.       if (curVidStream->non_intra_default)
  112.       {
  113.     qscale <<= 4;
  114.     coeff = ((short)level * (short)qscale) >> 3;
  115.     reconptr[pos] = coeff;
  116.  
  117.     if (curVidStream->picture.code_type != 4) {
  118.       recon_nonintra(qscale, run, reconptr);
  119.       flush_bits(2);
  120.     }
  121.  
  122.       } else {
  123.     iqmatrixptr = curVidStream->non_intra_quant_matrix_ptr[qscale];
  124.  
  125.     coeff = ((short)level * iqmatrixptr[run]) >> 3;
  126.     reconptr[pos] = coeff;
  127.  
  128.     if (curVidStream->picture.code_type != 4) {
  129.       recon_non2intra(run, iqmatrixptr, reconptr);
  130.       flush_bits(2);
  131.     }
  132.  
  133.       }
  134.     }
  135.     
  136.     j_rev_dct(reconptr);
  137. }
  138.     
  139. #undef DCT_recon 
  140. #undef DCT_dc_y_past 
  141. #undef DCT_dc_cr_past 
  142. #undef DCT_dc_cb_past 
  143.  
  144.  
  145.  
  146. /*
  147.  *--------------------------------------------------------------
  148.  *
  149.  * ParseAwayBlock --
  150.  *
  151.  *    Parses off block values, throwing them away.
  152.  *      Used with grayscale dithering.
  153.  *
  154.  * Results:
  155.  *    None.
  156.  *
  157.  * Side effects:
  158.  *      None.
  159.  *
  160.  * To do:
  161.  *      Move to sutils.s !!
  162.  *
  163.  *--------------------------------------------------------------
  164.  */
  165.  
  166. void ParseAwayBlock(int n)
  167. {
  168.   unsigned int diff, run;
  169.   int level;
  170.  
  171.   if (bufLength < 100) correct_underflow();
  172.  
  173.   if (curVidStream->mblock.mb_intra) {
  174.  
  175.     /* If the block is a luminance block... */
  176.  
  177.     if (n < 4) {
  178.       /* Parse and decode size of first coefficient and itself. */
  179.       DecodeDCTDCSizeLum(diff);
  180.     }
  181.     /* Otherwise, block is chrominance block... */
  182.     else {
  183.       /* Parse and decode size of first coefficient and itself. */
  184.       DecodeDCTDCSizeChrom(diff);
  185.     }
  186.   }
  187.   /* Otherwise, block is not intracoded... */
  188.   else {
  189.  
  190.     /* Decode and set first coefficient. */
  191.     DecodeDCTCoeffFirst(run, level);
  192.   }
  193.  
  194.   /* If picture is not D type (i.e. I, P, or B)... */
  195.  
  196.   if (curVidStream->picture.code_type != 4) {
  197.  
  198.     /* While end of macroblock has not been reached... */
  199.  
  200.     do {
  201.       DecodeDCTCoeffNext(run, level);    /* Get the dct_coeff_next */
  202.     } while (run != END_OF_BLOCK);
  203.  
  204.     /* End_of_block */
  205.     flush_bits(2);
  206.  
  207.   }
  208. }
  209.